package com.zhangye.test.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONObject;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;

/**
 * @Description: XML和map，list互转  
 * @Version: 1.0
 * @Author:聂紫晨
 * @Date:2016年12月6日17:18:39
 */
public class XMLPojoMapConverter {

	public static byte[] callMapToXML(Map map) {  
//      logger.info("将Map转成Xml, Map：" + map.toString());  
        StringBuffer sb = new StringBuffer();  
        sb.append("<xml>");  
        mapToXMLTest2(map, sb);  
        sb.append("</xml>");  
//      logger.info("将Map转成Xml, Xml：" + sb.toString());  
        try {  
            return sb.toString().getBytes("UTF-8");  
        } catch (Exception e) {  
//          logger.error(e);  
        }  
        return null;  
    }  
  
    private static void mapToXMLTest2(Map map, StringBuffer sb) {  
        Set set = map.keySet();  
        for (Iterator it = set.iterator(); it.hasNext();) {  
            String key = (String) it.next();  
            Object value = map.get(key);  
            if (null == value)  
                value = "";  
            if (value.getClass().getName().equals("java.util.ArrayList")) {  
                ArrayList list = (ArrayList) map.get(key);  
                sb.append("<" + key + ">");  
                for (int i = 0; i < list.size(); i++) {  
                    HashMap hm = (HashMap) list.get(i);  
                    mapToXMLTest2(hm, sb);  
                }  
                sb.append("</" + key + ">");  
            } else {  
                if (value instanceof HashMap) {  
                    sb.append("<" + key + ">");  
                    mapToXMLTest2((HashMap) value, sb);  
                    sb.append("</" + key + ">");  
                } else {  
                    sb.append("<" + key + ">" + value + "</" + key + ">");  
                }  
            }  
        }  
    }  
    
    public static Map xml2map(String xmlString) throws DocumentException {  
    	  Document doc = DocumentHelper.parseText(xmlString);  
    	  Element rootElement = doc.getRootElement();  
    	  Map<String, Object> map = new HashMap<String, Object>();  
    	  ele2map(map, rootElement);  
    	  System.out.println(map);  
    	  // 到此xml2map完成，下面的代码是将map转成了json用来观察我们的xml2map转换的是否ok  
    	  String string = JSONObject.fromObject(map).toString();  
    	  System.out.println(string);  
    	  return map;  
    	 } 
    
    
    static void ele2map(Map map, Element ele) {  
    	System.out.println(ele);  
    	// 获得当前节点的子节点  
    	List<Element> elements = ele.elements();  
    	if (elements.size() == 0) {  
    		// 没有子节点说明当前节点是叶子节点，直接取值即可  
    		map.put(ele.getName(), ele.getText());  
    	} else if (elements.size() == 1) {  
    		// 只有一个子节点说明不用考虑list的情况，直接继续递归即可  
    		Map<String, Object> tempMap = new HashMap<String, Object>();  
    		ele2map(tempMap, elements.get(0));  
    		map.put(ele.getName(), tempMap);  
    	} else {  
    		// 多个子节点的话就得考虑list的情况了，比如多个子节点有节点名称相同的  
    		// 构造一个map用来去重  
    		Map<String, Object> tempMap = new HashMap<String, Object>();  
    		for (Element element : elements) {  
    			tempMap.put(element.getName(), null);  
    		}  
    		Set<String> keySet = tempMap.keySet();  
    		for (String string : keySet) {  
    			Namespace namespace = elements.get(0).getNamespace();  
    			List<Element> elements2 = ele.elements(new QName(string,namespace));  
    			// 如果同名的数目大于1则表示要构建list  
    			if (elements2.size() > 1) {  
    				List<Map> list = new ArrayList<Map>();  
    				for (Element element : elements2) {  
    					Map<String, Object> tempMap1 = new HashMap<String, Object>();  
    					ele2map(tempMap1, element);  
    					list.add(tempMap1);  
    				}  
    				map.put(string, list);  
    			} else {  
    				// 同名的数量不大于1则直接递归去  
    				Map<String, Object> tempMap1 = new HashMap<String, Object>();  
    				ele2map(tempMap1, elements2.get(0));  
    				map.put(string, tempMap1);  
    			}  
    		}  
    	}  
    } 

}
